package org.eclipse.jdt.internal.ui.callhierarchy;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

public class DefaultWorkspaceVisitor implements WorkspaceVisitor {
	
	private LombokRefactor lombokRefactor;
	
	public void setLombokRefactor(LombokRefactor lombokRefactor) {
		this.lombokRefactor = lombokRefactor;
	}

	public boolean visit(IWorkspace workspace) {
		
		IWorkspaceRoot workspaceRoot = workspace.getRoot();
		try {
			if (workspace != null) {
				IProject[] projects = workspaceRoot.getProjects();
				if (projects != null
						&& projects.length > 0) {
					for (IProject project
							: projects) {
						try {
							visit(project);
						} catch (JavaModelException jme) {
							Logger.info("jme ex for " + project.getName() + ": " + jme.getMessage());
						} catch (Exception e) {
							Logger.info("unknown ex for " + project.getName() + ": " + e.getMessage());
						}
					}
				}
			}
		}  catch (Exception e) {
			Logger.info("unknown ex: " + e.getMessage());
		}
		
		return true;
	}

	public boolean visit(IProject project) throws JavaModelException {
		IJavaProject javaProject = JavaCore.create(project);
		if (javaProject != null) {
			visit(javaProject);
		}
		
		return true;
	}

	public boolean visit(IJavaProject javaProject) throws JavaModelException {
		IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots();
		
		if (packageFragmentRoots != null
				&& packageFragmentRoots.length > 0) {
			for (IPackageFragmentRoot packageFragmentRoot
					: packageFragmentRoots) {
				visit(packageFragmentRoot);
			}
		}
		
		return true;
	}

	public boolean visit(IPackageFragmentRoot packageFragmentRoot) throws JavaModelException {
		IJavaElement[] childs = packageFragmentRoot.getChildren();
		if (childs != null
				&& childs.length > 0) {
			for (IJavaElement childElement
					: childs) {
				if (childElement instanceof IPackageFragment) {
					IPackageFragment packageFragment = (IPackageFragment) childElement;
					visit(packageFragment);
				}
			}
		}
		return false;
	}

	public boolean visit(IPackageFragment packageFragment) throws JavaModelException {
		ICompilationUnit[] compilationUnits = packageFragment.getCompilationUnits();
		
		if (compilationUnits != null
				&& compilationUnits.length > 0) {
			for (ICompilationUnit compilationUnit
					: compilationUnits) {
				try {
					visit(compilationUnit);
				} catch (JavaModelException jme) {
					Logger.info("jme ex for " + compilationUnit.getElementName() + ": " + jme.getMessage());
				} catch (Exception e) {
					Logger.info("unknown ex for " + compilationUnit.getElementName() + ": " + e.getMessage());
				}
				
			}
		}
		
		return true;
	}

	public boolean visit(ICompilationUnit compilationUnit) throws JavaModelException {
		lombokRefactor.refactor(compilationUnit);
		return false;
	}
}
